<?php

require_once('classes/Util.class.php');
require_once('classes/StandardInnerConfig.class.php');

class RequestInterpreter{

    private $mapping = array();
    private $matchFound;
    private $dynamicExtentions = array('.htm', '.html', '');

    public function setDynamicExtention($ext){
        $this->dynamicExtentions[$ext] = $ext;
        return true;
    }

    public function getDynamicExtention(){
        return $this->dynamicExtentions;
    }

    private function includeFile($fileLocation){
        if (file_exists($fileLocation)){
            include($fileLocation);
            return true;
        }else{
            throw new Exception('Couldn\'t find the file '.$fileLocation);
        }
    }

    public function addConfigFromPhp($locationOfPhp){
        $this->includeFile($locationOfPhp);
    }

    public function addConfigFromXml($locationOfXml){
        $dom = new DOMDocument('1.0','UTF-8');
        $dom->load($locationOfXml);
        $classArray = Util::getMappingClassNameArray(false);
        $allNodes = $dom->firstChild->childNodes;
        for ($i = 0; $i < $allNodes->length; $i++){
            $node = $allNodes->item($i);
            $class = $node->localName;
            if (strlen($class) == 0) continue;
            if (in_array($class, $classArray)){
                require_once($file = 'classes/Mapping/'.$class.'.class.php');
                $class::interpretXmlConfig($node,$this);
            }else{
                throw new Exception('Class ['.$class.'] does not seem to exist.');
            }
        }
    }

    public function addMapping($mappingObj){
        if ($mappingObj instanceof RequestMapping){
            $this->mapping[] = $mappingObj;
            $mappingObj->setParentInterpreter($this);
            $mappingObj->setInnerConfigObj($innerMapping = new StandardInnerConfig());
            return $innerMapping;
        }else{
            throw new Exception('RequestMapping - map object of class ['.get_class($mappingObj).'] is not instanceof RequestMapping');
        }
    }

    public function hasMatch($uri){
        if ($this->matchFound !== null){
            return $this->matchFound;
        }
        foreach ($this->mapping as $mapper){
            if ($mapper->checkMapping($uri)){
                return $this->matchFound = $mapper;
            }
        }
    }

    public function runMatch(){
        if ($this->matchFound !== null){
            return $this->matchFound->run();
        }else{
            return null;
        }
    }

}

?>